package com.game.module.${moduleName ?lower_case}.protocol;

import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.google.protobuf.Parser;
import common.communication.protocol.ProtobufProtocol;
import io.netty.buffer.ByteBuf;
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
import com.game.module.${moduleName ?lower_case}.protocol.${moduleName}Protos.*;

/**
 * ${struct.comment}<br>
 * #{struct.protoId}<br>
 */
public class ${struct.baseName} extends ProtobufProtocol<${struct.name}> {

    public static final int ID = #{struct.protoId};
    
    <#if protoFields ? exists>
	<#list protoFields as field>
	/** ${field.comment}**/
	private ${field.javaType} ${field.name};
	</#list>
	</#if>
	
	<#-- Constructor -->
	public ${struct.baseName}(){
		<#if protoFields ? exists>
		<#list protoFields as field>
		<#if field.type == 'String'>
		this.${field.name} = "";
		<#elseif field.identifier == 'repeated'>
		this.${field.name} = new ArrayList<>();
		</#if>
		</#list>
		</#if>
	}
	
    <#if protoFields ? exists>
	<#list protoFields as field>
	/** ${field.comment}**/
	public ${field.javaType} get${field.name ? cap_first}(){
		return this.${field.name};
	}
	
	public void set${field.name ? cap_first}(${field.javaType} value){
		this.${field.name} = value;
	}
	<#if field.identifier == 'repeated'>
	public void add${field.name ? cap_first}(${field.javaTypeBase} value){
		this.${field.name}.add(value);
	}
	</#if>
	</#list>
	</#if>
	
	@Override
    public int getId() {
        return ID;
    }
    
    @Override
    public void encode(ByteBuf buffer) {
    }

    @Override
    public void decode(ByteBuf buffer) throws IOException {
    }
    
    @Override
    public Parser<${struct.name}> getParser() {
        return ${struct.name}.parser();
    }
    
    @Override
    public ${struct.name} buildProto() {
        ${struct.name}.Builder builder = ${struct.name}.newBuilder();
        <#if protoFields ? exists>
		<#list protoFields as field>
		<#if field.identifier == 'repeated'>
		<#if field.getPrimitive() == false>
		if (this.${field.name} != null && !this.${field.name}.isEmpty()) {
			for (int i = 0; i < this.${field.name}.size(); i++) {
                ${field.javaTypeBase} tmpData = this.${field.name}.get(i);
                builder.add${field.name?cap_first}(tmpData.buildProto());
            }
		}
		<#else>
		builder.addAll${field.name?cap_first}(this.${field.name});
		</#if>
		<#else>
		<#if field.getPrimitive() == true>
		builder.set${field.name ? cap_first}(${field.name});
		<#else>
        if (this.${field.name} != null) {
            builder.set${field.name?cap_first}(this.${field.name}.buildProto());
        }
		</#if>
		</#if>
		</#list>
		</#if>
		return builder.build();       
    }
    
     @Override
    public void parseProto(${struct.name} proto) {
    	<#if protoFields ? exists>
		<#list protoFields as field>
		<#if field.getPrimitive()>
		<#if field.identifier == 'repeated'>
		this.${field.name}.addAll(proto.get${field.name?cap_first}List());
		<#else>
		this.${field.name} = proto.get${field.name?cap_first}();
		</#if>
		<#else>
		<#if field.identifier == 'repeated'>
		List<${field.javaTypeBase}Proto> ${field.name}List = proto.get${field.name?cap_first}List();
        if (${field.name}List != null && !${field.name}List.isEmpty()) {
            for (int i = 0; i < ${field.name}List.size(); i++) {
                ${field.javaTypeBase}Proto tmpProto = ${field.name}List.get(i);
                ${field.javaTypeBase} tmpMsg = new ${field.javaTypeBase}();
                tmpMsg.parseProto(tmpProto);
                this.${field.name}.add(tmpMsg);
            }
        }
        <#else>
        if (proto.has${field.name?cap_first}()) {
            ${struct.name} ${field.name}Proto = proto.get${field.name?cap_first}();
            this.${field.name} = new ${field.type}();
            this.${field.name}.parseProto(${field.name}Proto);
        }
		</#if>
		</#if>
		
		</#list>
		</#if>
		
    }
    
    @Override
    public String toString() {
        return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }

}